import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
//klasa Socket reprezentuje polączenie sieciowe pomiędzy dwoma komputerami
//dla serwera przeznaczono klasę ServerSocket.
///klasa Socket - obsługa klienta
//Socket i ServerSocket wykorzystują Transfer Control Protocol (TCP) do komunikacji przez Internet (klient-serwer) 


public class Server {
	static String poprawnaLiczbaRegexp = "^[0-1]+$";
	static String poprawneDzialaneRegexp = "^['\\+','\\*','\\/','\\-']+$";
	static String poprawnyAdresIPRegexp = "^(?:[0-9]{1,3}\\.){3}[0-9]{1,3}$";

	private static int port = 1793;
	private ServerSocket server = null;
	
	static int[] gracze = new int[6];
	static int ilosc_graczy = 0;
	static boolean wypisz[] = new boolean[6];
	private static int boty;
	static String boty_name[] = new String[5];
	static String[] gracze_name;
	static int pieniadze;
	Talia talia = new Talia();

	/**
	 * Aplikacja serwera towrzy gniazdo ServerSocket na określnonym porcie;
	 * klasa ServerSocket - oczekuje na ządania klientów kirowane na port o
	 * określonym numerze
	 */
	public Server() {
		try {
			server = new ServerSocket(port);
		} catch (IOException e) {
			System.out.println(e.getMessage());
			e.printStackTrace();
			System.exit(-1);

		}

	}

	/**
	 * Serwer tworzy nowe gniazdo służące do komunikacji z klientem; metoda
	 * accept() blokuje działanie programu i wznawia go dopiero po odebraniu
	 * żądania połączenia przesłanego przez klienta; aplikacja serwera realizuje
	 * nieskończoną pętlę, w której oczekuje żądania nadsyłane przez klientów
	 */
	public void listenSocket() {
		System.out.println("Czekanie na polczenie od klienta...");
		ConnectionHandler connection[] = new ConnectionHandler[6];
		int i = 0;
		while (true) {// główna pętla serwera
			try {
				// stworz gniazdo
				
					connection[i] = new ConnectionHandler(server.accept(), i);
					i++;
				//ilosc_graczy++;
				//talia.
			} catch (IOException e) {
				System.out.println("Accept failed: 4444");
				System.exit(-1);
			}
		}
		
	}

	/**
	 * zwrócony (do metody listenSocket) obiekt Socket operuje na innym porcie
	 * niż gniazdo serwera - ServerSocket - dzięki czemu gniazdo serwera
	 * ponownie może oczekiwać na żądania zgłaszane przez inne klienty; do
	 * każdego wątku przekazywane jest nowe gniazdo, co umożliwiają obsługę
	 * kilku żądań (klientów) naraz
	 * 
	 */
	class ConnectionHandler implements Runnable {
		private Socket socket;
		ObjectInputStream strumienWejsciowy;
		ObjectOutputStream strumienWyjsciowy;
		int id;

		public ConnectionHandler(Socket socket, int id) {
			this.socket = socket;
			this.id = id;

			Thread t = new Thread(this);
			t.start();
		}

		/**
		 * metoda run() należy do obiektu Runnable, jest ona umieszczona na
		 * samym spodzie stosu noweg wątku, określa zadanie jakie wątek ma
		 * wykonywać; wewnątrz metody wykonywana jest pętla (do momentu
		 * odebrania komunikatu "end" od klienta oznaczającego koniec pracy
		 * wątku i klienta), która odbiera zadanie od klienta, wykonuje
		 * obliczenia i wysyła odpowiedź
		 */
		public void run() {

			System.out.println("nazwiazano polaczenie z klientem " + socket.getInetAddress());
			System.out.println("Czekanie na wiadomosc od klienta... ");

			try {

				strumienWejsciowy = new ObjectInputStream(socket.getInputStream());
				strumienWyjsciowy = new ObjectOutputStream(socket.getOutputStream());
				String message = String.valueOf(strumienWejsciowy.readObject());
				System.out.println(message);
				gracze_name[id] = message;
				strumienWyjsciowy.writeObject(id);
				while (!message.equals("end")){
					message = (String) strumienWejsciowy.readObject();
					System.out.println(message);
					if (message.equals("ID")){
						String s = Integer.toString(id);
						strumienWyjsciowy.writeObject(s);
					}
					else if (message.equals("ilosc")){
						String s = Integer.toString(boty+ilosc_graczy);
						strumienWyjsciowy.writeObject(s);
					}
					else if (message.equals("boty")){
						String s = Integer.toString(boty);
						strumienWyjsciowy.writeObject(s);
					}
					else if (message.equals("gracze")) {
						String s = Integer.toString(ilosc_graczy);
						strumienWyjsciowy.writeObject(s);
					}
					else if (message.equals("kasa")) {
						String s = Integer.toString(pieniadze);
						strumienWyjsciowy.writeObject(s);
					}
					else if (message.equals("boty 0")) {
						strumienWyjsciowy.writeObject(boty_name[0]);
					}
					else if (message.equals("boty 1")) {
						strumienWyjsciowy.writeObject(boty_name[1]);
					}
					else if (message.equals("boty 2")) {
						strumienWyjsciowy.writeObject(boty_name[2]);
					}
					else if (message.equals("boty 3")) {
						strumienWyjsciowy.writeObject(boty_name[3]);
					}
					else if (message.equals("boty 4")) {
						strumienWyjsciowy.writeObject(boty_name[4]);
					}
					else if (message.equals("boty 5")) {
						strumienWyjsciowy.writeObject(boty_name[5]);
					}
					else if (message.equals("gracze 0")) {
						if (gracze_name.equals(null))
							strumienWyjsciowy.writeObject("brak");
						else
							strumienWyjsciowy.writeObject(gracze_name[0]);
					}
					else if (message.equals("gracze 1")) {
						if (gracze_name.equals(null))
							strumienWyjsciowy.writeObject("brak");
						else
							strumienWyjsciowy.writeObject(gracze_name[1]);
					}
					else if (message.equals("gracze 2")) {
						if (gracze_name.equals(null))
							strumienWyjsciowy.writeObject("brak");
						else
							strumienWyjsciowy.writeObject(gracze_name[2]);
					}
					else if (message.equals("gracze 3")) {
						if (gracze_name.equals(null))
							strumienWyjsciowy.writeObject("brak");
						else
							strumienWyjsciowy.writeObject(gracze_name[3]);
					}
					else if (message.equals("gracze 4")) {
						if (gracze_name.equals(null))
							strumienWyjsciowy.writeObject("brak");
						else
							strumienWyjsciowy.writeObject(gracze_name[4]);
					}
					else if (message.equals("gracze 5")) {
						if (gracze_name.equals(null))
							strumienWyjsciowy.writeObject("brak");
						else
							strumienWyjsciowy.writeObject(gracze_name[5]);
					}
				}
					
				System.out.println("Klient konczy polaczenie z adresu: " + socket.getInetAddress());
				strumienWyjsciowy.close();
				strumienWejsciowy.close();
				socket.close();
				}
			
             catch (IOException e) {

            } catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
			
		
		public void wyslij(String wiadomosc){
			//strumienWyjsciowy.writeObject("");
		}
		
	}

	public static void main(String[] args) {

		if (args.length != 0) {
			if (args.length == 1) {
				try {
					port = Integer.parseInt(args[0]);
				} catch (NumberFormatException ex) {
					System.out.println("nieprawidło podany numer portu");
					System.exit(-1);
				}
			} else
				System.out.println("Nieprawidło podane dane z linii poleceń, \nustawiono domyślny numer portu");
		}
		Scanner klawiatura = new Scanner(System.in);
		System.out.println("Ilosc pieniedzy:");
		pieniadze = klawiatura.nextInt();
		System.out.println("podaj ilosc botów:");
		boty = klawiatura.nextInt();
		for (int i = 0; i < boty; i++) {
            boty_name[i] = klawiatura.next();
		}
		System.out.println("podaj ilosc graczy:");
		ilosc_graczy = klawiatura.nextInt();
		gracze_name = new String[ilosc_graczy];
		Server example = new Server();
		example.listenSocket();
		example.stopSerwer();

	}

	/**
	 * zamknięcie gniazda
	 */
	private void stopSerwer() {
		try {
			server.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
